package com.browsesoft.dbtools.sqlserver;

import java.io.File;
import java.io.FileInputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

/**
 * 代表一个表结构描述文件，可以从该文件中得到所有表结构。该文件格式为从sqlserver 中导出的表结构文件格式。
 */
public final class TableStructFile {
	/**
	 * 存放文件内容
	 */
	private String context;

	/**
	 * 表结构列表
	 */
	private Collection tableStructs = new LinkedList();

	/**
	 * 表名及其结构对应关系
	 */
	private Map tableNameAndStructs = new HashMap();

	/**
	 * 使用文件名构造
	 */
	public TableStructFile(String fileName) {
		try {
			// 文件
			File file = new File(fileName);
			// 文件流
			FileInputStream is = new FileInputStream(file);
			int len = (int) file.length();
			byte[] buffer = new byte[len];
			// 读入文件内容
			is.read(buffer);
			// 得到文本内容
			this.context = new String(buffer);
			is.close();
			// 装载表结构
			this.loadTableStructs();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 得到表结构列表
	 * 
	 * @return 表结构列表
	 */
	public Collection getTableStructs() {
		return this.tableStructs;
	}

	/**
	 * 装载表结构，语句格式如下 CREATE TABLE [dbo].[lack] ( [yh_id] [char] (10) NOT NULL ,
	 * [yh_name] [varchar] (30) NULL , [date11] [char] (8) NULL , [date1] [char]
	 * (8) NULL , [money1] [decimal](18, 2) NULL , [month] [char] (8) NULL ,
	 * [lack1] [decimal](18, 2) NULL , [lack2] [decimal](18, 2) NULL , [znj_old]
	 * [decimal](18, 2) NULL ) ON [PRIMARY]
	 */
	private void loadTableStructs() {
		// 对于每一条create table语句
		int index = this.context.indexOf("CREATE TABLE");
		while (index != -1) {
			// 得到表名
			int sindex = this.context.indexOf("[", index);
			sindex = this.context.indexOf("[", sindex + 1);
			int eindex = this.context.indexOf("]", sindex);
			String tableName = this.context.substring(sindex + 1, eindex);
			// 得到表中所有字段
			Collection fields = this.loadFieldStructs(eindex);
			// 产生一个表结构放到结果中
			TableStruct tableStruct = new TableStruct(tableName, fields);
			this.tableStructs.add(tableStruct);
			// 给表名与结构的对照关系中放值
			this.tableNameAndStructs.put(tableName, tableStruct);
			// 继续找下一个表
			index = this.context.indexOf("CREATE TABLE", eindex);
		}
	}

	/**
	 * 装载表中所有字段
	 * 
	 * @param index
	 *            开始装载位置
	 */
	private Collection loadFieldStructs(int index) {
		Collection result = new LinkedList();
		// 得到表结构字段部分的开始位置
		int start = this.context.indexOf("(", index);
		int end = this.context.indexOf("GO", start);
		// 对于每一个字段描述
		while (start < end && start != -1) {
			// 得到字段名
			int nstart = this.context.indexOf("[", start);
			int nend = this.context.indexOf("]", nstart);
			// 生成字段放到列表中
			String name = this.context.substring(nstart + 1, nend);
			result.add(new FieldStruct(name));
			// 继续下一个
			start = this.context.indexOf(",\r", nend);
		}
		return result;
	}

	/**
	 * 转换成字符串
	 */
	public String toString() {
		String result = "";
		// 对于每一个表
		Iterator iter = this.getTableStructs().iterator();
		while (iter.hasNext()) {
			TableStruct item = (TableStruct) iter.next();
			// 转换表结构
			result += item;
		}
		return result;
	}

	/**
	 * 得到某个表的结构
	 * 
	 * @param tableName
	 *            表名
	 */
	public TableStruct getTableStruct(String tableName) {
		return (TableStruct) this.tableNameAndStructs.get(tableName);
	}
}

/**
 * 表结构
 */
class TableStruct {
	/**
	 * 表名
	 */
	private String tableName;

	/**
	 * 字段结构列表
	 */
	public Collection fields;

	/**
	 * 使用表名构造
	 */
	public TableStruct(String tableName) {
		this(tableName, null);
	}

	/**
	 * 使用表名以及字段结构构造
	 */
	public TableStruct(String tableName, Collection fields) {
		this.tableName = tableName;
		this.fields = fields;
	}

	/**
	 * 得到表名
	 */
	public String getTableName() {
		return this.tableName;
	}

	/**
	 * 增加字段
	 */
	public void addField(FieldStruct field) {
		this.fields.add(field);
	}

	/**
	 * 转换成字符串
	 */
	public String toString() {
		String result = "";
		// 转换表名
		result += "tableName: " + this.tableName + "\n";
		// 对于每一个字段
		Iterator iter = this.fields.iterator();
		while (iter.hasNext()) {
			FieldStruct item = (FieldStruct) iter.next();
			// 转换字段
			result += item + "\n";
		}
		return result;
	}
}

/**
 * 字段结构
 */
class FieldStruct {
	/**
	 * 字段名
	 */
	private String name;

	/**
	 * 根据字段名构造
	 */
	public FieldStruct(String name) {
		this.name = name;
	}

	/**
	 * 得到字段名
	 * 
	 * @return 字段名
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * 转换成字符串
	 */
	public String toString() {
		return this.name;
	}
}